<template>
  <div>
    <!-- 地图信息框 -->
    <div v-if="selectedHospital" class="map-info-box">
      <div class="info-box-header">
        <h4>{{ selectedHospital.deptName }}</h4>
        <el-button type="text" class="close-btn" @click="closeInfoBox">×</el-button>
      </div>
      <div class="info-box-content">
        <div class="info-item">
          <span class="info-label">筛查人数：</span>
          <span class="info-value">{{ selectedHospital.screenCount || '无数据' }}</span>
        </div>
        <div class="info-item">
          <span class="info-label">DNT：</span>
          <span class="info-value">{{ selectedHospital.dnt || '无数据' }}</span>
        </div>
        <div class="info-item">
          <span class="info-label">DPT：</span>
          <span class="info-value">{{ selectedHospital.dpt || '无数据' }}</span>
        </div>
        <div class="info-item">
          <span class="info-label">DRT：</span>
          <span class="info-value">{{ selectedHospital.drt || '无数据' }}</span>
        </div>
      </div>
    </div>
    <div class="search-box">
      <el-button type="primary" style="margin-left: 16px" @click="downloadData">导出</el-button>
      <el-button v-if="cityViewActive || districtViewActive" type="success" style="margin-left: 16px" @click="handleReturn">返回</el-button>
    </div>
    <div id="map" style="width: 100%; height: calc(100vh - 60px)"></div>
  </div>
</template>
<script>
  import {
    queryHospital,
    exportData
  } from "@/api/atlas/index";

  import "ol/ol.css";
  import Map from "ol/Map.js";
  import View from "ol/View.js";
  import TileLayer from "ol/layer/Tile.js";
  import { fromLonLat, toLonLat } from "ol/proj";
  import XYZ from "ol/source/XYZ.js";
  import { Circle as CircleGeometry } from 'ol/geom';
  import { Circle } from 'ol/geom';
  import VectorLayer from 'ol/layer/Vector.js';
  import VectorSource from 'ol/source/Vector.js';
  import GeoJSON from 'ol/format/GeoJSON.js';
  import { Stroke, Fill, Style, Icon, Text } from 'ol/style.js';
  import Point from 'ol/geom/Point.js';
  import Feature from 'ol/Feature.js';
  import shanxiCityData from './山西省.json';
  // 静态引入所有市级JSON数据
  import taiyuanData from './太原市.json';
  import datongData from './大同市.json';
  import yangquanData from './阳泉市.json';
  import changzhiData from './长治市.json';
  import jinchengData from './晋城市.json';
  import shuozhouData from './朔州市.json';
  import jinzhongData from './晋中市.json';
  import yunchengData from './运城市.json';
  import xinzhouData from './忻州市.json';
  import linyiData from './临汾市.json';
  import lvliangData from './吕梁市.json';

  const cityDataMap = {
    '太原市': taiyuanData,
    '大同市': datongData,
    '阳泉市': yangquanData,
    '长治市': changzhiData,
    '晋城市': jinchengData,
    '朔州市': shuozhouData,
    '晋中市': jinzhongData,
    '运城市': yunchengData,
    '忻州市': xinzhouData,
    '临汾市': linyiData,
    '吕梁市': lvliangData,
  };

  export default {
    data() {
      return {
        map: null,
        hospitalList: [],
        cityViewActive: false, // 控制是否为城市视图
        provinceLayer: null, // 省级图层
        districtLayer: null, // 区县图层
        highlightLayer: null, // 单独高亮的区县图层
        hospitalLayer: null, // 医院标记图层
        hospitalCircleLayer: null, // 医院范围圆圈图层
        districtViewActive: false, // 控制是否为区县视图
        hospitalDialogVisible: false, // 控制医院详情弹窗显示
        selectedHospital: null, // 当前选中的医院信息
        hospitalColors: {}, // 存储每个医院的颜色
      };
    },
    created() {
      // this.getColorData();
      this.getHospitalLocation('140000');
      this.getConfigKeyNoToken("sys.system.atlas.range").then((response) => {
        this.range = response.msg;
      });
    },
    methods: {
      // 导出数据
      downloadData() {
        const that = this;
        this.$modal.confirm("是否确认导出所有的医院数据？").then(() => {
          // 导出
          // return that.download(exportData, { ...params }, `接口分类.xlsx`);
          exportData({ param: {} })
            .then((res) => {
              // const url = window.URL.createObjectURL(new Blob([res]));
              const blob = new Blob([res]);
              this.$download.saveAs(blob, "辖区内指控数据.xlsx");
              this.$message.success("导出成功");
            })
            .catch((error) => {
              this.$message.success("下载Excel失败:", error);
              console.error("下载Excel失败:", error);
            });
        });
      },
      // 查询当前医院,并且返回经纬度
      // 生成随机颜色
      getRandomColor() {
        const letters = '789ABCDEF';
        let color = '#';
        for (let i = 0; i < 6; i++) {
          color += letters[Math.floor(Math.random() * letters.length)];
        }
        return color;
      },

      // 为医院添加范围圆圈
      addHospitalCircle(hospital) {
        const circleSource = this.hospitalCircleLayer.getSource();
        const center = [Number(hospital.lng), Number(hospital.lat)];

        // 为每个医院生成或获取颜色
        if (!this.hospitalColors[hospital.deptId]) {
          this.hospitalColors[hospital.deptId] = this.getRandomColor();
        }

        const baseColor = this.hospitalColors[hospital.deptId];
        const radius = 0.02; // 10公里半径（米）

        // 创建医院标记点（用于显示名称）
        const marker = new Feature({
          geometry: new Point(fromLonLat([Number(hospital.lng), Number(hospital.lat)]))
        });

        // 设置标记点样式（只显示文字）
        marker.setStyle(
          new Style({
            text: new Text({
              text: hospital.hospitalName,
              offsetY: -radius * 100000, // 根据半径调整文字位置，使其显示在圆上方
              font: '14px Microsoft YaHei',
              fill: new Fill({ color: '#000' }),
              stroke: new Stroke({
                color: '#fff',
                width: 3
              }),
              textBaseline: 'bottom',
              textAlign: 'center'
            })
          })
        );

        // 使用 Circle 类创建圆形
        const circle = new Feature(
          new Circle(center, radius).transform('EPSG:4326', 'EPSG:3857')
        );

        // 设置圆圈样式
        circle.setStyle(
          new Style({
            fill: new Fill({
              color: `${baseColor}66` // 66 表示 40% 透明度
            })
          })
        );

        // 先添加圆圈，再添加标记点，确保标记点显示在上层
        circleSource.addFeature(circle);
        circleSource.addFeature(marker);

        circle.set('hospitalId', hospital.id);
      },

      getHospitalLocation(areaCode) {
        const param = {
          areaCode: areaCode + '',
          // startDate: "",
          // endDate: "",
        };
        queryHospital(param).then((res) => {
          this.hospitalList = [...res.data];
          // 只有在地图尚未初始化时才调用initMap
          if (!this.map) {
            this.initMap();
          }

          // 清空现有标记和圆圈
          const source = this.hospitalLayer.getSource();
          source.clear();
          this.hospitalCircleLayer.getSource().clear();
          this.hospitalColors = {}; // 清空颜色缓存

          // 添加新标记和圆圈
          this.hospitalList.forEach(hospital => {
            if (hospital.lng && hospital.lat) {
              const marker = new Feature({
                geometry: new Point(fromLonLat([Number(hospital.lng), Number(hospital.lat)]))
              });
              // 存储医院信息到要素属性中
              marker.set('name', hospital.deptName);
              marker.set('id', hospital.id);
              source.addFeature(marker);

              // 为医院添加范围圆圈
              this.addHospitalCircle(hospital);
            }
          });

          // 调整视图以显示所有标记
          // if (source.getFeatures().length > 0) {
          //   this.map.getView().fit(source.getExtent(), {
          //     padding: [50, 50, 50, 50],
          //     maxZoom: 14
          //   });
          // }
        });
      },
      handleReturn() {
        if (this.districtViewActive) {
          this.resetToCityView();
        } else if (this.cityViewActive) {
          this.resetToProvinceView();
        }
      },

      resetToCityView() {
        // 隐藏高亮图层并清空
        this.highlightLayer.getSource().clear();
        this.highlightLayer.setVisible(false);

        // 重新显示区县图层
        this.districtLayer.setVisible(true);

        // 视图返回到整个市的范围
        this.map.getView().fit(this.districtLayer.getSource().getExtent(), {
            duration: 500,
            padding: [50, 50, 50, 50],
            maxZoom: 12
        });

        this.districtViewActive = false;

        // 重新查询当前市的数据
        // 假设区县GeoJSON的properties中存在parent.adcode字段
        const features = this.districtLayer.getSource().getFeatures();
        if (features.length > 0) {
            const parentInfo = features[0].get('parent');
            if (parentInfo && parentInfo.adcode) {
                this.getHospitalLocation(parentInfo.adcode);
            } else {
                console.warn('Could not find parent adcode to re-fetch hospital data.');
            }
        }
      },

      // 显示医院详情
      showHospitalDetail(hospital) {
      console.log('hospital: ', hospital);
        // Create a new object reference to ensure Vue detects the change
        this.selectedHospital = {...hospital};

        // If the info box was closed, we need to force update the DOM
        if (!this.selectedHospital) {
          this.$nextTick(() => {
            this.selectedHospital = {...hospital};
          });
        }
      },

      closeInfoBox() {
        this.selectedHospital = null;
      },

      resetToProvinceView() {
        // 隐藏区县图层并清空数据
        this.districtLayer.getSource().clear();
        this.districtLayer.setVisible(false);

        // 同时清空并隐藏高亮图层，防止闪烁
        this.highlightLayer.getSource().clear();
        this.highlightLayer.setVisible(false);

        // 显示省级图层
        this.provinceLayer.setVisible(true);

        // 恢复地图视野到全省
        this.map.getView().animate({
          center: fromLonLat([112.556197, 37.876857]),
          zoom: 7,
          duration: 500
        });

        // 隐藏返回按钮
        this.cityViewActive = false;
        this.districtViewActive = false; // 确保区县视图状态也被重置
        this.getHospitalLocation('140000'); // 重新查询全省数据
      },

      drillToCity(feature) {
        const cityName = feature.get('name');
        if (!cityName) {
            console.error('Clicked feature has no name property:', feature.getProperties());
            return;
        }

        const cityData = cityDataMap[cityName];
        if (cityData) {
          const districtFeatures = new GeoJSON().readFeatures(cityData, {
              dataProjection: 'EPSG:4326',
              featureProjection: 'EPSG:3857'
          });

          const districtSource = this.districtLayer.getSource();
          districtSource.clear();
          districtSource.addFeatures(districtFeatures);
          this.districtLayer.setVisible(true);
          this.provinceLayer.setVisible(false);

          this.map.getView().fit(districtSource.getExtent(), {
            duration: 500,
            padding: [50, 50, 50, 50],
            maxZoom: 12
          });

          this.cityViewActive = true;
          this.getHospitalLocation(feature.get('adcode'));
        } else {
            alert(`未找到“${cityName}”的地图数据，请检查数据是否已引入。`);
        }
      },

      drillToDistrict(feature) {
        // 隐藏区县图层
        this.districtLayer.setVisible(false);

        // 在高亮图层中只显示被点击的区县
        const highlightSource = this.highlightLayer.getSource();
        highlightSource.clear();
        highlightSource.addFeature(feature);
        this.highlightLayer.setVisible(true);

        // 缩放到该区县
        this.map.getView().fit(feature.getGeometry().getExtent(), {
            duration: 500,
            padding: [100, 100, 100, 100],
            maxZoom: 14
        });

        this.districtViewActive = true;
        this.getHospitalLocation(feature.get('adcode'));
      },

      initMap(mapList) {
        // --- 省级图层设置 ---
        const provinceSource = new VectorSource({
          features: new GeoJSON().readFeatures(shanxiCityData, {
            dataProjection: 'EPSG:4326',
            featureProjection: 'EPSG:3857'
          })
        });
        const cityStyle = new Style({
          stroke: new Stroke({ color: '#a0cfff', width: 2 }), // 浅蓝色边框
          fill: new Fill({ color: 'rgba(160, 207, 255, 0.2)' }) // 非常浅的蓝色填充
        });
        this.provinceLayer = new VectorLayer({
          source: provinceSource,
          style: cityStyle
        });

        // --- 区县图层设置 (初始为空) ---
        const districtStyle = new Style({
          stroke: new Stroke({ color: '#a0cfff', width: 2 }), // 浅蓝色边框
          fill: new Fill({ color: 'rgba(160, 207, 255, 0.2)' }) // 非常浅的蓝色填充
        });
        this.districtLayer = new VectorLayer({
          source: new VectorSource(),
          style: districtStyle,
          visible: false // 默认隐藏
        });

        // --- 高亮图层设置 ---
        const highlightStyle = new Style({
          stroke: new Stroke({ color: '#a0cfff', width: 2 }), // 浅蓝色边框
          fill: new Fill({ color: 'rgba(160, 207, 255, 0.2)' }) // 非常浅的蓝色填充
        });
        this.highlightLayer = new VectorLayer({
            source: new VectorSource(),
            style: highlightStyle,
            visible: false
        });

        // --- 医院标记图层 ---
        this.hospitalLayer = new VectorLayer({
          source: new VectorSource(),
          style: (feature) => {
            const style = new Style({
              // image: new Icon({
              //   anchor: [0.5, 1],  // 图标锚点位置，[0.5, 1] 表示图标底部中心
              //   scale: 0.1,  // 放大图标，原来是0.05
              //   src: require('./医院.png')
              // }),
              text: new Text({
                text: feature.get('name') || '',
                offsetY: -20,  // 文字在图标上方的偏移量
                font: 'bold 14px Microsoft YaHei',
                fill: new Fill({ color: '#000' }),
                stroke: new Stroke({
                  color: '#fff',
                  width: 3
                }),
                textBaseline: 'bottom',
                textAlign: 'center'
              })
            });
            return style;
          }
        });

        // --- 医院范围圆圈图层 ---
        // 创建医院标记图层（用于显示名称）
        this.hospitalMarkerLayer = new VectorLayer({
          source: new VectorSource(),
          zIndex: 10 // 确保标记显示在最上层
        });

        // 创建医院范围圆圈图层
        this.hospitalCircleLayer = new VectorLayer({
          source: new VectorSource(),
          zIndex: 1 // 确保圆圈在标记下面
        });

        // --- 地图初始化 ---
        this.map = new Map({
          target: "map",
          layers: [
            // new TileLayer({ source: new XYZ({ url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png' }) }),
            new TileLayer({ source: new XYZ({ url: apiUrl + "/profile/tiles_img_gaode_china_large/{z}/{x}/{y}.png" }) }),
            this.provinceLayer,
            this.districtLayer,
            this.highlightLayer,
            this.hospitalCircleLayer,
            this.hospitalMarkerLayer,
            this.hospitalLayer,
          ],
          view: new View({
            center: fromLonLat([112.556197, 37.876857]),
            zoom: 7,
            minZoom: 6,
            maxZoom: 18
          }),
        });

        // --- 添加点击事件 ---
        this.map.on('click', (e) => {
        console.log('e:  1231312', e);
          // 首先检查是否点击了医院标记
          const hospitalFeature = this.map.forEachFeatureAtPixel(e.pixel, (feature) => feature, {
            layerFilter: (layer) => layer === this.hospitalLayer
          });
        console.log('hospitalFeature: ', hospitalFeature);

          if (hospitalFeature) {
            const name = hospitalFeature.get('name');
            const hospital = this.hospitalList.find(h => h.deptName === name);
            if (hospital) {
              this.showHospitalDetail(hospital);
              return; // 处理完医院点击后直接返回
            }
          }

          // 如果没有点击医院标记，则处理下钻事件
          // 省级视图 -> 市级视图
          if (!this.cityViewActive) {
            const feature = this.map.forEachFeatureAtPixel(e.pixel, (feature) => feature, {
              layerFilter: (layer) => layer === this.provinceLayer
            });
            if (feature) {
              this.drillToCity(feature);
            }
            return; // 处理完毕，退出
          }

          // 市级视图 -> 区县视图
          if (this.cityViewActive && !this.districtViewActive) {
            const feature = this.map.forEachFeatureAtPixel(e.pixel, (feature) => feature, {
              layerFilter: (layer) => layer === this.districtLayer
            });
            if (feature) {
              this.drillToDistrict(feature);
            }
          }
        });
      },
    },
  };
</script>
<style scoped>
  /* 地图信息框样式 */
  .map-info-box {
    position: absolute;
    top: 80px;
    left: 20px;
    width: 280px;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    z-index: 1000;
    overflow: hidden;
    font-family: 'Microsoft YaHei', sans-serif;
  }

  .info-box-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 15px;
    background-color: #409EFF;
    color: white;
  }

  .info-box-header h4 {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
  }

  .close-btn {
    color: white;
    font-size: 18px;
    padding: 0;
    margin: 0;
    line-height: 1;
  }

  .close-btn:hover {
    color: #e6f7ff;
  }

  .info-box-content {
    padding: 15px;
  }

  .info-item {
    display: flex;
    margin-bottom: 8px;
    font-size: 13px;
    line-height: 1.5;
  }

  .info-item:last-child {
    margin-bottom: 0;
  }

  .info-label {
    color: #606266;
    width: 70px;
    flex-shrink: 0;
  }

  .info-value {
    color: #303133;
    font-weight: 500;
    flex: 1;
    word-break: break-all;
  }

  .length-box2 {
    height: 180px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    margin-left: 4px;
  }

  .level-box {
    position: fixed;
    right: 24px;
    bottom: 24px;
  }

  .color-box {
    display: flex;
    align-items: center;
    /* margin-top: 8px; */
    font-size: 14px;
  }

  .color-div {
    height: 18px;
    width: 24px;
    margin: 0 16px;
  }

  .search-box {
    position: absolute;
    left: 30px;
    top: 0;
    width: 100%;
    height: 56px;
    padding-left: 16px;
    display: flex;
    align-items: center;
    z-index: 999;
  }
</style>
